package com.authentication.successhandler;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.authentication.RBACUser;
import com.authorization.storage.AuthorityStorageManager;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.interfaces.RSAPublicKey;
import java.sql.Date;
import java.time.LocalDateTime;
import java.time.ZoneId;

import static com.common.Constant.*;

/**
 * @author 罗俊华
 * @since 2023/11/29 20:19
 */

public class CreatingTokenSuccessHandler implements AuthenticationSuccessHandler {


    private static final ObjectMapper objectMapper = new ObjectMapper();

    private final AuthorityStorageManager<GrantedAuthority> authorityStorageManager;

    public CreatingTokenSuccessHandler(AuthorityStorageManager<GrantedAuthority> authorityStorageManager) {
        this.authorityStorageManager = authorityStorageManager;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        if (!(authentication.getPrincipal() instanceof RBACUser)) {
            throw new AuthenticationServiceException("不支持把非RBACUser对象解析为令牌");
        }

        RBACUser principal = (RBACUser) authentication.getPrincipal();
        try {
//            RSAPublicKey publicKey = new RSAPublicKeyImpl(RSA_PUBLIC_KEY.getBytes(StandardCharsets.UTF_8));

            Algorithm algorithm = Algorithm.none();
            LocalDateTime expiredTime = LocalDateTime.now().plusHours(1);


            String token = JWT.create()
                    .withIssuer(principal.getUsername())
                    .withClaim(JWT_USER_ID, principal.getUserId())
                    .withClaim(JWT_DEPT_ID, principal.getDeptId())
                    .withClaim(JWT_EXPIRED_AT, Date.from(expiredTime.atZone(ZoneId.systemDefault()).toInstant()))
                    .sign(algorithm);

            ImmutableMap<String, ? extends Serializable> map = ImmutableMap.of("code", 200, "token", token, "userName", authentication.getName());
            String load = objectMapper.writeValueAsString(map);

//          存储已认证授权信息
            authorityStorageManager.storage(authentication);

            response.getWriter().write(load);

        } catch (JWTCreationException e) {
            // Invalid Signing configuration / Couldn't convert Claims.
        }
    }
}
